#include <iostream>
#include <cstring>
#include <sys/sem.h>
#include <sys/shm.h>
#include <unistd.h>
#include <cstdio>
#include <cstdlib>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <cassert>

typedef struct
{
    int val;
    int semid; //信号集id
} Storage;

void sig_wait(int signo)
{
    if (signo == SIGCHLD)
    {
        wait(0);
    }
    wait(0);
}

void init(Storage *s)
{
    //创建信号量集(包含两个信号量)
    if ((s->semid = semget(IPC_CREAT, 2, IPC_CREAT | IPC_EXCL | 0777)) < 0)
    {

        perror("semget");
        exit(1);
    }

    //对所有信号集中的所有信号量初始化
    union semun
    {
        int val;
        struct semid_ds *ds;
        unsigned short *array;
    };

    union semun un;
    //信号量初值设置为0
    unsigned short array[2] = {0, 0};
    un.array = array;
    if (semctl(s->semid, 0, SETALL, un) < 0)
    {
        perror("semctl error");
        exit(1);
    }
}
void destroy(Storage *s)
{
    assert(s != NULL);
    if (semctl(s->semid, 0, IPC_RMID, NULL) < 0)
    {
        perror("semctl");
        exit(1);
    }
    free(s);
}

void write(Storage *s, int val)
{
    //写入操作
    s->val = val;
    std::cout << "写入：" << val << std::endl;
    // v

    struct sembuf ops_v[1] = {{0, 1, SEM_UNDO}};

    struct sembuf ops_p[1] = {{1, -1, SEM_UNDO}};

    if (semop(s->semid, ops_v, 1) < 0)
    {
        perror("semop");
        exit(1);
    }

    if (semop(s->semid, ops_p, 1) < 0)
    {
        perror("semop");
        exit(1);
    }

    // p
}

void read(Storage *s)
{

    assert(s != NULL);

    struct sembuf ops_p[1] = {{0, -1, SEM_UNDO}};

    struct sembuf ops_v[1] = {{1, 1, SEM_UNDO}};

    if (semop(s->semid, ops_p, 1) < 0)
    {
        perror("semop error");
        exit(1);
    }
    if (semop(s->semid, ops_v, 1) < 0)
    {
        perror("semop");
        exit(1);
    }

    std::cout << "read message:" << s->val << std::endl;
}



// int main()

//     // if(signal(SIGCHLD,sig_wait)==SIG_ERR){
//     //     perror("signal");
//     //     exit(1);
//     // }

//     int shmid;
//     if((shmid=shmget(IPC_PRIVATE,sizeof(Storage),IPC_CREAT|IPC_EXCL|0777))<0){
//         perror("shmat error");
//         exit(1);

//     }

//     //物理内存与共享内存的映射
//     Storage*s=(Storage*)shmat(shmid,0,0);
//     if(s==(Storage*)-1){
//         perror("shmat error");
//         exit(1);
//     }


//     pid_t pid=fork();
//     if (pid< 0)
//     {
//         perror("fork");
//         exit(1);
//     }
//     else if (pid == 0)
//     {
//         //子进程
//     }
//     else
//     {
//         //父进程
//     }

//     return 0;
// }

// #endif